package org.qpcr.community.standalone.web.response.dashboard;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 仪表板数据对象
 */
public class DashboardData {
    private List<StatItem> productStats;
    private List<StatItem> deviceStats;
    private List<StatItem> todayStats;
    private List<ExperimentTrend> experimentTrend;

    // 构造函数
    public DashboardData() {}

    public DashboardData(List<StatItem> productStats, List<StatItem> deviceStats,
                         List<StatItem> todayStats, List<ExperimentTrend> experimentTrend) {
        this.productStats = productStats;
        this.deviceStats = deviceStats;
        this.todayStats = todayStats;
        this.experimentTrend = experimentTrend;
    }

    // Getter 和 Setter
    public List<StatItem> getProductStats() {
        return productStats;
    }

    public void setProductStats(List<StatItem> productStats) {
        this.productStats = productStats;
    }

    public List<StatItem> getDeviceStats() {
        return deviceStats;
    }

    public void setDeviceStats(List<StatItem> deviceStats) {
        this.deviceStats = deviceStats;
    }

    public List<StatItem> getTodayStats() {
        return todayStats;
    }

    public void setTodayStats(List<StatItem> todayStats) {
        this.todayStats = todayStats;
    }

    public List<ExperimentTrend> getExperimentTrend() {
        return experimentTrend;
    }

    public void setExperimentTrend(List<ExperimentTrend> experimentTrend) {
        this.experimentTrend = experimentTrend;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DashboardData that = (DashboardData) o;
        return Objects.equals(productStats, that.productStats) &&
                Objects.equals(deviceStats, that.deviceStats) &&
                Objects.equals(todayStats, that.todayStats) &&
                Objects.equals(experimentTrend, that.experimentTrend);
    }

    @Override
    public int hashCode() {
        return Objects.hash(productStats, deviceStats, todayStats, experimentTrend);
    }

    @Override
    public String toString() {
        return "DashboardData{" +
                "productStats=" + productStats +
                ", deviceStats=" + deviceStats +
                ", todayStats=" + todayStats +
                ", experimentTrend=" + experimentTrend +
                '}';
    }

    /**
     * 创建完全随机的仪表板示例数据
     * @param experimentDate 实验日期范围参数：today、week、month
     * @return DashboardResponse 包含随机模拟数据的响应对象
     */
    public static DashboardData createMockData(String experimentDate) {

        Random random = new Random();

        // 随机生成产品数量统计数据
        int totalProducts = 20 + random.nextInt(50); // 20-70个产品
        int normalProducts = (int)(totalProducts * (0.7 + random.nextDouble() * 0.2));
        List<StatItem> productStats = Arrays.asList(
            new StatItem("正常", normalProducts, "#52c41a"),
            new StatItem("禁用", totalProducts - normalProducts, "#d9d9d9")
        );

        // 随机生成设备数量统计数据
        int totalDevices = 30 + random.nextInt(100); // 30-130个设备
        int onlineDevices = (int)(totalDevices * (0.5 + random.nextDouble() * 0.3));
        int offlineDevices = (int)(totalDevices * (0.1 + random.nextDouble() * 0.2));
        int runningDevices = (int)(totalDevices * (0.05 + random.nextDouble() * 0.15));
        int faultDevices = totalDevices - onlineDevices - offlineDevices - runningDevices;

        List<StatItem> deviceStats = Arrays.asList(
            new StatItem("在线", onlineDevices, "#52c41a"),
            new StatItem("离线", offlineDevices, "#d9d9d9"),
            new StatItem("实验中", runningDevices, "#1890ff"),
            new StatItem("故障", faultDevices, "#f5222d")
        );

        // 随机生成今日实验统计数据
        int totalTodayExperiments = 10 + random.nextInt(40); // 10-50个实验
        int completedExperiments = (int)(totalTodayExperiments * (0.2 + random.nextDouble() * 0.4));
        int unfinishedExperiments = (int)(totalTodayExperiments * (0.3 + random.nextDouble() * 0.4));
        int abnormalExperiments = totalTodayExperiments - completedExperiments - unfinishedExperiments;

        List<StatItem> todayStats = Arrays.asList(
            new StatItem("完成", completedExperiments, "#52c41a"),
            new StatItem("未完成", unfinishedExperiments, "#d9d9d9"),
            new StatItem("异常", abnormalExperiments, "#f5222d")
        );

        // 根据传入的参数生成实验趋势数据
        List<ExperimentTrend> experimentTrend = generateExperimentTrend(experimentDate, random);

        // 构建数据对象
        return new DashboardData(productStats, deviceStats, todayStats, experimentTrend);
    }

    /**
     * 根据实验日期范围生成实验趋势数据
     * @param experimentDate 实验日期范围参数：today、week、month
     * @param random 随机数生成器
     * @return 实验趋势数据列表
     */
    private static List<ExperimentTrend> generateExperimentTrend(String experimentDate, Random random) {
        List<ExperimentTrend> experimentTrend = new ArrayList<>();

        // 处理experimentDate为null或空字符串的情况，默认使用week
        if (experimentDate == null || experimentDate.trim().isEmpty()) {
            experimentDate = "week";
        }

        // 获取日期范围
        Map<String, LocalDateTime> dateRange = ExperimentDateEnums.getDateRange(experimentDate);
        LocalDateTime startDate = dateRange.get("start");
        LocalDateTime endDate = dateRange.get("end");

        // 根据不同的时间范围生成不同数量的数据点
        switch (experimentDate) {
            case "today":
                // 今日：生成24小时的数据点
                for (int i = 0; i < 24; i++) {
                    LocalDateTime currentTime = startDate.plusHours(i);
                    String date = currentTime.format(DateTimeFormatter.ofPattern("HH:mm"));
                    int completed = 5 + random.nextInt(20); // 5-25个完成实验
                    int abnormal = random.nextInt(8); // 0-8个异常实验
                    experimentTrend.add(new ExperimentTrend(date, completed, abnormal));
                }
                break;
            case "week":
                // 近一周：生成7天的数据点
                for (int i = 0; i < 7; i++) {
                    LocalDateTime currentDate = startDate.plusDays(i);
                    String date = currentDate.format(DateTimeFormatter.ofPattern("MM-dd"));
                    int completed = 15 + random.nextInt(85); // 15-100个完成实验
                    int abnormal = random.nextInt(25); // 0-25个异常实验
                    experimentTrend.add(new ExperimentTrend(date, completed, abnormal));
                }
                break;
            case "month":
                // 近一个月：生成30天的数据点
                for (int i = 0; i < 30; i++) {
                    LocalDateTime currentDate = startDate.plusDays(i);
                    String date = currentDate.format(DateTimeFormatter.ofPattern("MM-dd"));
                    int completed = 20 + random.nextInt(80); // 20-100个完成实验
                    int abnormal = random.nextInt(30); // 0-30个异常实验
                    experimentTrend.add(new ExperimentTrend(date, completed, abnormal));
                }
                break;
            default:
                // 默认生成近一周的数据
                for (int i = 0; i < 7; i++) {
                    LocalDateTime currentDate = LocalDateTime.now().minusDays(6 - i);
                    String date = currentDate.format(DateTimeFormatter.ofPattern("MM-dd"));
                    int completed = 15 + random.nextInt(85); // 15-100个完成实验
                    int abnormal = random.nextInt(25); // 0-25个异常实验
                    experimentTrend.add(new ExperimentTrend(date, completed, abnormal));
                }
                break;
        }

        return experimentTrend;
    }
}